package com.cssiot.weixin.basic.util;
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.TriggerBuilder.newTrigger;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
/**
 * 处理定时任务调度队列
* @ClassName: QuartzFactoryUtil 
* @Description: TODO （描述）
* @author 作者 jacking
* @date 2016年12月19日 下午1:56:19
 */
public class QuartzFactoryUtil {
	private static Logger logger = LoggerFactory.getLogger(QuartzFactoryUtil.class);
	private static Map<String,String> jobs=new HashMap<String, String>();
	public  static int minu=10;
	/**
	 * 默认cron 当前0分钟开始，间隔10分钟
	 */
	public static String DEFAULT_CRON_EXPRESSION = "0 0/10 * * * ?";  
	/**
	 * 任务名称
	 */
    public static String JOB_NAME = "GZZ01";  
    /**
	 * 触发器名称
	 */
    public static String TRIGGER_NAME = "GZZ01"; 
    /**
	 * 任务名称组别
	 */
    public static String JOB_GROUP_NAME = "GZZ01_JOB_GROUP";  
    /**
	 * 触发器名称组别
	 */
    public static String TRIGGER_GROUP_NAME = "GZZ01_TRIGGER_GROUP"; 
    private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();  
    private QuartzFactoryUtil(){}
    /** 
     * @Description: 添加一个定时任务 
     * @param jobName 任务名 
     * @param jobGroupName  任务组名 
     * @param triggerName 触发器名 
     * @param triggerGroupName 触发器组名 
     * @param jobClass  任务 
     * @param cron   时间设置，参考quartz说明文档  
     */  
    public static void addJob(String jobName, String jobGroupName, 
            String triggerName, String triggerGroupName, Class<? extends Job> jobClass, String cron,Map<String,Object> params) {  
        try {  
        	
        	if(findModifyJobExist(jobName, jobGroupName, triggerName, triggerGroupName, cron)){
    			return;
    		}
        	
        	jobs.put(jobName, jobName);
            Scheduler sched = schedulerFactory.getScheduler();  
            // 任务名，任务组，任务执行类
            JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
            
            if(null!=params&&params.size()>0){
            	JobDataMap dataMap=jobDetail.getJobDataMap();
            	 for(Entry<String, Object> entry:params.entrySet()){
        			 String key=entry.getKey();
        			 Object value=entry.getValue();
        			 dataMap.put(key, value);
        		 }
            }
            // 触发器  
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            // 触发器名,触发器组  
            triggerBuilder.withIdentity(triggerName, triggerGroupName);
            triggerBuilder.startNow();
            // 触发器时间设定  
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // 创建Trigger对象
            CronTrigger trigger = (CronTrigger) triggerBuilder.build();

            // 调度容器设置JobDetail和Trigger
            sched.scheduleJob(jobDetail, trigger);  
            // 启动  
            if (!sched.isShutdown()) {  
                sched.start();  
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
    public static void addJob(String jobName, String jobGroupName, Class<? extends Job> jobClass, String cron,Map<String,Object> params) {  
    	try {  
    		if(findModifyJobExist(jobName, jobGroupName, cron)){
    			return;
    		}
    		jobs.put(jobName, jobName);
    		Scheduler sched = schedulerFactory.getScheduler();  
    		// 任务名，任务组，任务执行类
    		JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
    		   if(null!=params&&params.size()>0){
               	JobDataMap dataMap=jobDetail.getJobDataMap();
               	 for(Entry<String, Object> entry:params.entrySet()){
           			 String key=entry.getKey();
           			 Object value=entry.getValue();
           			 dataMap.put(key, value);
           		 }
               }
    		// 触发器  
    		TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
    		// 触发器名,触发器组  
    		triggerBuilder.withIdentity(jobName, jobGroupName);
    		triggerBuilder.startNow();
    		// 触发器时间设定  
    		triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
    		// 创建Trigger对象
    		CronTrigger trigger = (CronTrigger) triggerBuilder.build();
    		
    		// 调度容器设置JobDetail和Trigger
    		sched.scheduleJob(jobDetail, trigger);  
    		// 启动  
    		if (!sched.isShutdown()) {  
    			sched.start();  
    		}  
    	} catch (Exception e) {  
    		throw new RuntimeException(e);  
    	}  
    }  

    /** 
     * @Description: 修改一个任务的触发时间
     *  
     * @param jobName 
     * @param jobGroupName
     * @param triggerName 触发器名
     * @param triggerGroupName 触发器组名 
     * @param cron   时间设置，参考quartz说明文档   
     */  
    public static void modifyJobTime(String jobName, 
            String jobGroupName, String triggerName, String triggerGroupName, String cron) {  
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);  
            if (trigger == null) {  
                return;  
            }  
            String oldTime = trigger.getCronExpression();  
            if (!oldTime.equalsIgnoreCase(cron)) { 
                /** 方式一 ：调用 rescheduleJob 开始 */
                // 触发器  
                TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
                // 触发器名,触发器组  
                triggerBuilder.withIdentity(triggerName, triggerGroupName);
                triggerBuilder.startNow();
                // 触发器时间设定  
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
                // 创建Trigger对象
                trigger = (CronTrigger) triggerBuilder.build();
                // 方式一 ：修改一个任务的触发时间
                sched.rescheduleJob(triggerKey, trigger);
                /** 方式一 ：调用 rescheduleJob 结束 */

                /** 方式二：先删除，然后在创建一个新的Job  */
                //JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));  
                //Class<? extends Job> jobClass = jobDetail.getJobClass();  
                //removeJob(jobName, jobGroupName, triggerName, triggerGroupName);  
                //addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron); 
                /** 方式二 ：先删除，然后在创建一个新的Job */
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
    public static boolean findModifyJobExist(String jobName, 
    		String jobGroupName, String triggerName, String triggerGroupName, String cron) {  
    	boolean isExist=false;
    	try {  
    		Scheduler sched = schedulerFactory.getScheduler();  
    		TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
    		CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);  
    		if (trigger == null) { 
    			return isExist;  
    		}  
    		String oldTime = trigger.getCronExpression();  
    		if (!oldTime.equalsIgnoreCase(cron)) {
    			isExist=true;
    			/** 方式一 ：调用 rescheduleJob 开始 */
    			// 触发器  
    			TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
    			// 触发器名,触发器组  
    			triggerBuilder.withIdentity(triggerName, triggerGroupName);
    			triggerBuilder.startNow();
    			// 触发器时间设定  
    			triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
    			// 创建Trigger对象
    			trigger = (CronTrigger) triggerBuilder.build();
    			// 方式一 ：修改一个任务的触发时间
    			sched.rescheduleJob(triggerKey, trigger);
    			/** 方式一 ：调用 rescheduleJob 结束 */
    			
    			/** 方式二：先删除，然后在创建一个新的Job  */
    			//JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));  
    			//Class<? extends Job> jobClass = jobDetail.getJobClass();  
    			//removeJob(jobName, jobGroupName, triggerName, triggerGroupName);  
    			//addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron); 
    			/** 方式二 ：先删除，然后在创建一个新的Job */
    		}  
    		
    		isExist=true;
    	} catch (Exception e) {  
    		throw new RuntimeException(e);  
    	}
		return isExist;  
    }  
    public static boolean findModifyJobExist(String jobName, 
    		String jobGroupName, String cron) {  
    	boolean isExist=false;
    	try {  
    		Scheduler sched = schedulerFactory.getScheduler();  
    		TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
    		CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);  
    		if (trigger == null) { 
    			return isExist;  
    		}  
    		String oldTime = trigger.getCronExpression();  
    		if (!oldTime.equalsIgnoreCase(cron)) {
    			isExist=true;
    			/** 方式一 ：调用 rescheduleJob 开始 */
    			// 触发器  
    			TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
    			// 触发器名,触发器组  
    			triggerBuilder.withIdentity(jobName, jobGroupName);
    			triggerBuilder.startNow();
    			// 触发器时间设定  
    			triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
    			// 创建Trigger对象
    			trigger = (CronTrigger) triggerBuilder.build();
    			// 方式一 ：修改一个任务的触发时间
    			sched.rescheduleJob(triggerKey, trigger);
    			/** 方式一 ：调用 rescheduleJob 结束 */
    			
    			/** 方式二：先删除，然后在创建一个新的Job  */
    			//JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));  
    			//Class<? extends Job> jobClass = jobDetail.getJobClass();  
    			//removeJob(jobName, jobGroupName, triggerName, triggerGroupName);  
    			//addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron); 
    			/** 方式二 ：先删除，然后在创建一个新的Job */
    		}  
    		
    		isExist=true;
    	} catch (Exception e) {  
    		throw new RuntimeException(e);  
    	}
    	return isExist;  
    }  
    public static void modifyJobTime(String jobName, 
    		String jobGroupName,String cron) {  
    	try {  
    		Scheduler sched = schedulerFactory.getScheduler();  
    		TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
    		CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);  
    		if (trigger == null) {  
    			return;  
    		}  
    		String oldTime = trigger.getCronExpression();  
    		if (!oldTime.equalsIgnoreCase(cron)) { 
    			/** 方式一 ：调用 rescheduleJob 开始 */
    			// 触发器  
    			TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
    			// 触发器名,触发器组  
    			triggerBuilder.withIdentity(jobName, jobGroupName);
    			triggerBuilder.startNow();
    			// 触发器时间设定  
    			triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
    			// 创建Trigger对象
    			trigger = (CronTrigger) triggerBuilder.build();
    			// 方式一 ：修改一个任务的触发时间
    			sched.rescheduleJob(triggerKey, trigger);
    			/** 方式一 ：调用 rescheduleJob 结束 */
    			
    			/** 方式二：先删除，然后在创建一个新的Job  */
    			//JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));  
    			//Class<? extends Job> jobClass = jobDetail.getJobClass();  
    			//removeJob(jobName, jobGroupName, triggerName, triggerGroupName);  
    			//addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron); 
    			/** 方式二 ：先删除，然后在创建一个新的Job */
    		}  
    	} catch (Exception e) {  
    		throw new RuntimeException(e);  
    	}  
    }  

    /** 
     * @Description: 移除一个任务 
     *  
     * @param jobName 
     * @param jobGroupName 
     * @param triggerName 
     * @param triggerGroupName 
     */  
    public static void removeJob(String jobName, String jobGroupName,  
            String triggerName, String triggerGroupName) {  
        try {  
        	jobs.remove(jobName);
            Scheduler sched = schedulerFactory.getScheduler();  
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            sched.pauseTrigger(triggerKey);// 停止触发器  
            sched.unscheduleJob(triggerKey);// 移除触发器  
            sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
    /** 
     * @Description: 移除一个任务 
     *  
     * @param jobName 
     * @param jobGroupName 
     * @param triggerName 
     * @param triggerGroupName 
     */  
    public static void removeJob(String jobName, String jobGroupName) {  
    	try {  
    		jobs.remove(jobName);
    		Scheduler sched = schedulerFactory.getScheduler();  
    		TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
    		sched.pauseTrigger(triggerKey);// 停止触发器  
    		sched.unscheduleJob(triggerKey);// 移除触发器  
    		sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务  
    	} catch (Exception e) {  
    		throw new RuntimeException(e);  
    	}  
    }  

    /** 
     * @Description:启动所有定时任务 
     */  
    public static void startJobs() {  
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  
            sched.start();  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  

    /** 
     * @Description:关闭所有定时任务 
     */  
    public static void shutdownJobs() {  
        try {  
            Scheduler sched = schedulerFactory.getScheduler();  
            if (!sched.isShutdown()) {  
                sched.shutdown();  
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
    
    /**
     * @Description: 暂停一个定时任务 
     * @param name
     * @param group
     */
    public void pauseJob(String name, String group){
        try {
        	 Scheduler scheduler = schedulerFactory.getScheduler(); 
            JobKey jobKey = JobKey.jobKey(name, group);
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
    /**
     * @description: 恢复一个任务
     * @param name
     * @param group
     */
    public void resumeJob(String name, String group){
        try {
        	 Scheduler scheduler = schedulerFactory.getScheduler(); 
            JobKey jobKey = JobKey.jobKey(name, group);         
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }       
    }
    /**
     * @Description: 修改一个定时任务
     * @param name
     * @param group
     * @param cronExpression
     */
    public void modifyTime(String name, String group, String cronExpression){       
        try {
        	 Scheduler scheduler = schedulerFactory.getScheduler(); 
            TriggerKey tk = TriggerKey.triggerKey(name, group);
            //构造任务触发器
            Trigger trg = newTrigger()
                    .withIdentity(name, group)
                    .withSchedule(cronSchedule(cronExpression))
                    .build();       
            scheduler.rescheduleJob(tk, trg);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
	public static Map<String, String> getJobs() {
		return jobs;
	}
	 
    
}